package org.hairball;

import org.hairball.cli.CommandLineParseException;
import org.hairball.cli.CommandLineParser;
import org.hairball.cli.Option;

import java.io.File;
import java.util.HashSet;
import java.util.Map;

public class ConfigReader {
    private CommandLineParser cliParser = new CommandLineParser(
          new Option(FORMAT_ARGNAME, "The format to use. 'dot' and 'graphml' are supported. Defaults to dot", "dot"),
          new Option(CLASS_JAR_ARGNAME, "The class jar to analyse"),
          new Option(ANALYSIS_ARGNAME, "The type of analsis to run. 'constructorInjection', 'setterInjection' and 'all' are supported. Defaults to 'all'", "all"),
          new Option(OUTPUT_ARGNAME, "The file to output to"),
          new Option(INCLUDE_PACKAGES_ARGNAME, "A comma seperated list of packages to include in analysis, e.g. java.lang,java.util", "*"),
          new Option(MIN_DEPENDENCIES_ARGNAME, "The minimum number of dependencies a node has to have before " +
                                                "it will be displayed. If a node has enough dependencies, all its " +
                                                "direct dependencies will be shown.", "0")
    );
    
    private static final String INCLUDE_PACKAGES_ARGNAME = "-includePackages";
    private static final String MIN_DEPENDENCIES_ARGNAME = "-minDeps";
    private static final String FORMAT_ARGNAME = "-format";
    private static final String CLASS_JAR_ARGNAME = "-classJar";
    private static final String ANALYSIS_ARGNAME = "-analysis";
    private static final String OUTPUT_ARGNAME = "-output";

    public Configuration read(String... args) throws CommandLineParseException {
        HashSet<AnalysisType> analysisTypes = new HashSet<AnalysisType>();

        Map<String, String> values = cliParser.parse(args);
        String jarFilename = values.get(CLASS_JAR_ARGNAME);
        String format = values.get(FORMAT_ARGNAME);
        String outputFile = values.get(OUTPUT_ARGNAME);
        String analysis = values.get(ANALYSIS_ARGNAME);
        String packagesToInclude[] = splitPackages(values.get(INCLUDE_PACKAGES_ARGNAME));

        if (analysis.equals("all")) {
            analysisTypes.add(AnalysisType.CONSTRUCTOR_INJECTION);
            analysisTypes.add(AnalysisType.SETTER_INJECTION);
        } else {
            try {
                analysisTypes.add(AnalysisType.getForDisplayName(analysis));
            } catch (UnsupportedAnalysisType unsupportedAnalysisType) {
                throw new CommandLineParseException("Analysis " + analysis + " is not supported", cliParser.usage());
            }
        }

        File jarFile = new File(jarFilename);
        if (!jarFile.exists()) {
            throw new CommandLineParseException(jarFilename + " does not exist", cliParser.usage());
        }

        boolean validFormat = format.equalsIgnoreCase("dot") || format.equalsIgnoreCase("graphml");
        if (!validFormat) {
            throw new CommandLineParseException("Format " + format + " is not supported. Use 'dot' or 'graphml'", cliParser.usage());
        }

        return new Configuration(jarFilename, Format.getForDisplayName(format), outputFile, analysisTypes, packagesToInclude);
    }

    private String[] splitPackages(String commaSeperatedPackages) {
        if (!commaSeperatedPackages.equals("*")) {
            return commaSeperatedPackages.split(",");
        } else {
            return new String[0];
        }
    }
}
